<template>
    <canvas id="canvas"></canvas>
</template>

<script setup>
import { onMounted } from 'vue';
import { Engine3D, Scene3D, Object3D, Camera3D, LitMaterial, BoxGeometry, MeshRenderer, DirectLight, HoverCameraController, View3D, AtmosphericComponent, ComponentBase, Time, Color  } from '@orillusion/core'

onMounted(() => {
    init();
});

// 光照动画脚本组件
const lightAnimationComponent = () => {
    class LightAnimationComponent extends ComponentBase {
        init(){
            this.light = null;
            this.color = null;
        }
        
        start () {
            this.light = this.object3D.getComponent(DirectLight);
            this.color = this.light.lightColor;
        }
        
        onUpdate(){
            this.color.r = Math.pow(Math.sin(Time.time * 0.001), 10);
            this.light.lightColor = this.color;
        }
    }
    
    return LightAnimationComponent;
};

// 材质动画脚本组件
const materialAnimationComponent = () => {
    class MaterialAnimationComponent extends ComponentBase {
        init(){
            this.material = null;
        }
        
        start(){
            let mr = this.object3D.getComponent(MeshRenderer);
            this.material = mr.material;
        }
        
        onUpdate(){
            let delta = Time.time * 0.001;
            this.material.baseColor = new Color(Math.sin(delta), Math.cos(delta), Math.sin(delta));
        }
    }
    
    return MaterialAnimationComponent;
};

// 路径动画脚本组件
const pathAnimationComponent = () => {
    class PathAnimationComponent extends ComponentBase {
        onUpdate() {
            this.object3D.x = Math.sin(Time.time * 0.001) * 2;
            this.object3D.y = Math.cos(Time.time * 0.001) * 2;
        }
    }
    
    return PathAnimationComponent;
};

const init = async () => {
    const LightAnimationComponent = lightAnimationComponent();
    const MaterialAnimationComponent = materialAnimationComponent();
    const PathAnimationComponent = pathAnimationComponent();
    
    // 初始化引擎
    let canvas = document.getElementById('canvas')
    await Engine3D.init({
      canvasConfig: { canvas }
    });

    // 新建场景
    let scene3D = new Scene3D();
    
    // 添加天空盒 - 添加大气散射天空组件
    scene3D.addComponent(AtmosphericComponent);
    
    // 添加摄像机控件
    let cameraObj = new Object3D();
    let camera = cameraObj.addComponent(Camera3D);
    // 根据窗口大小设置摄像机视角
    camera.perspective(60, window.innerWidth / window.innerHeight, 1, 5000.0);
    // 设置相机控制器
    let controller = camera.object3D.addComponent(HoverCameraController);
    controller.setCamera(-135, -25, 25)
    // 添加相机节点
    scene3D.addChild(cameraObj);
    
    // 添加光照
    let light = new Object3D();
    // 添加平行光组件
    let component = light.addComponent(DirectLight);
    // 调整光照参数
    light.rotationX = -45
    light.rotationZ = -45
    component.lightColor = new Color(1.0, 0, 0, 1)
    component.intensity = 10
    // 添加自定义组件
    light.addComponent(LightAnimationComponent);
    // 添加光照对象
    scene3D.addChild(light);
    
    // 新建对象并为其添加MeshRenderer - 为对象添加 MeshRenderer 后，我们需要将几何体和材质挂载到对象的 MeshRenderer 上
    // 新建对象
    const obj = new Object3D();
    // 为对象添加 MeshRenderer
    let mr = obj.addComponent(MeshRenderer);
    // 设置几何体
    mr.geometry = new BoxGeometry(5, 5, 5);
    // 设置材质
    mr.material = new LitMaterial();
    // 添加自定义组件
    obj.addComponent(MaterialAnimationComponent);
    obj.addComponent(PathAnimationComponent);
    // 将物体对象添加到场景中
    scene3D.addChild(obj);
    
    // 渲染场景
    // 创建View3D对象
    let view = new View3D();
    // 指定渲染场景
    view.scene = scene3D;
    // 指定使用的相机
    view.camera = camera;
    // 开始渲染
    Engine3D.startRenderView(view);
   
};
</script>

<style scoped>
    #canvas{
        width: 100vw;
        height: 100vh;
    }
</style>